package com.cs.beneficios.common;

import java.sql.Connection;
//import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

//import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.sql.DataSource;

//import oracle.jdbc.OracleDriver;


public class ConnectionFactory 
{
  //Produccion
  private static final String JDNI_DATASOURCE = "jdbc/ds_beneficios";
  //private static final String JDBC_URL = "jdbc:oracle:thin:@10.1.220.122:1521:sub";
  //private static final String JDBC_URL = "jdbc:oracle:thin:@10.1.220.91:1521:sub";

  //Desarrollo
  //private static final String JDNI_DATASOURCE = "jdbc/ds_beneficiosDS";
  //private static final String JDBC_URL = "jdbc:oracle:thin:@10.1.220.123:1521:sub";
  //private static final String JDBC_URL = "jdbc:oracle:thin:@10.70.4.250:1521:sub";
  //private static final String JDBC_URL = "jdbc:oracle:thin:@192.168.1.2:1521:sub";
  

  //private String strEsquema;
  //private String strPwd;
  private Connection conn;
  private DataSource ds;
  public int contador=0;
  PreparedStatement pstmt = null;
  
  /*public ConnectionFactory(String strEsquema, String strPwd) 
  {
    this.strEsquema = strEsquema;
    this.strPwd = strPwd;
  }*/
    
  public Connection getConnection() throws SQLException {
      Connection conn = null; 
      try {
        InitialContext initctx = new InitialContext();
        ds = (DataSource)initctx.lookup(JDNI_DATASOURCE);
        conn = ds.getConnection();
        //ConnectionAdministrator connAdm = new ConnectionAdministrator();
        //contador = connAdm.connectionAdministratorSum(contador);
        //System.out.println("Abiertas "+String.valueOf(contador));
      }
      catch (NamingException e) {
        System.out.println("Error getting the connection: " + e.getMessage());
      }
      
      return conn;
   } // End getConnection

  /*public Connection getConnectionWithDriver() throws SQLException
  {
    String strDriver = "oracle.jdbc.driver.OracleDriver";
    String strUrl = JDBC_URL;
      try{
          //Instancio la clase del driver, su constructor invoca a DriverManager 
          //para que lo registre en memoria
          Class.forName(strDriver).newInstance(); 
          System.out.println("Driver cargado");

          //Creo la conexion
          conn = DriverManager.getConnection(strUrl,strEsquema,strPwd);
          //System.out.println("Conexion establecida");
      }
      catch(ClassNotFoundException cnfe ){
          //Esta excepcion lo lanza el m�todo forName(strDriver)
          cnfe.printStackTrace();
          System.out.println("Error : Driver no encontrado : " + cnfe.getMessage());
      }
      catch(InstantiationException ie){
          //Esta excepcion lo lanza el m�todo newInstance()
          ie.printStackTrace();
          System.out.println("Ocurrio un error instanciando el driver " + ie.getMessage());
      }                
      catch(IllegalAccessException iae){
          //Al igual que InstantiationException, esta excepcion lo lanza el m�todo newInstance()
          iae.printStackTrace();
          System.out.println("Ocurrio un error de acceso, instanciando el driver " + iae.getMessage());
      }
      return conn;
  }*/
  
//    public Connection getConnWithDriverClob() throws SQLException {
//        DriverManager.registerDriver(new OracleDriver());
//        String dbUrl = JDBC_URL;
//        Properties props = new Properties(); 
//        props.put("user", strEsquema);
//        props.put("password",strPwd); 
//        props.put("SetBigStringTryClob", "true");
//        conn = DriverManager.getConnection(dbUrl, props);
//        //System.out.println("Conexion establecida");
//        return conn;
//    }
  
  public void closeConnection(Connection con) throws SQLException {
      if (con != null && !con.isClosed()) {
        if(pstmt != null)
        {
          pstmt.close();
        }
        con.close();
        //ConnectionAdministrator connAdm = new ConnectionAdministrator();
        //contador = connAdm.connectionAdministratorRest(contador);
        //System.out.println("Cerradas "+String.valueOf(contador));
      }
   } // End closeConnection
  
  /**
    * M�todo que busca la cantidad de ocurrencias de un caracter en una cadena
    *
    * @param strToken Cadena en que se buscar� el caracter strSearch
    * @strSearch Caracter a buscar
    * @return int con la cantidad de ocurrencias en una cadena
    */
    public int getOcurrencesCount(String strToken, char strSearch){
        int iStart = 0;
        int icontOcur = 0;
        while (strToken.indexOf(strSearch,iStart) != -1){
          icontOcur ++;
          iStart = strToken.indexOf(strSearch,iStart) + 1;
        }
        return icontOcur;
    }
    
    
    /**
    * Valida que los par�metros enviados a un SQL esten completos y correctos
    * @param String strSql instruccion SQL
    * @param parPrepar arreglo con los par�metros del SQL, si el SQL no lleva parametros este valor ser�a null
    * @return PreparedStatement, en caso que haya un problema con los par�metros se retornar�a null
    */     
    private PreparedStatement getPstmtWithArguments(String strSql , String parPrepar[], Connection conn ) throws SQLException{
        
        pstmt = conn.prepareStatement(strSql);
        if (parPrepar != null){
            int iOcurrencesCount = getOcurrencesCount(strSql,'?');
            if (iOcurrencesCount !=  parPrepar.length){
                System.err.println("Se tiene " + iOcurrencesCount + " ? en el SQL del PreparedStatement  para " + parPrepar.length + " par�metros marcados. No se ejecuto la instruccion.");
            }
            for (int i = 0; i < parPrepar.length; i ++){
                pstmt.setString(i+1, parPrepar[i]);
            }
        }
        
        return pstmt;
    }
    
    
    /**
    * Metodo que ejecuta un comando SQL con instrucciones preparadas
    *
    * @param strSql Dml (Insert, update, delete) SQL
    * @param parPrepar arreglo que determinan los par�metros marcados de la instruccion preparada, su dimension debe ser igual a cuantos ? halla en strSql si su valor es null, indica que el SQL no tiene parametros
    * @return cantidad de registros afectados
    */
    public int execSql(String strSql, String parPrepar[], Connection conn) throws SQLException{
        pstmt = getPstmtWithArguments(strSql, parPrepar, conn); 
        return pstmt.executeUpdate();
    }
        
    
    
    
    /**
    * Metodo ejecuta una consulta realizada con instrucciones preparadas
    *
    * @param strQuery Consulta SQL
    * @param parPrepar arreglo que determinan los par�metros marcados de la
    * instruccion preparada, su dimension debe ser igual a cuantos ? halla en query, 
    * si la consulta no necesita par�metros su valor ser�a null
    * @return CachedRowSetImpl
    */
    public ResultSet getRecordsRset(String strQuery, String parPrepar[], Connection conn) throws SQLException{
        ResultSet rst;
        pstmt = getPstmtWithArguments(strQuery, parPrepar, conn);
		rst = pstmt.executeQuery();
        return rst;
    }
    
    
//    public CachedRowSet getRecordsRsetCache(String strQuery, String parPrepar[], Connection conn) throws SQLException{
//      ResultSet rst;
//      PreparedStatement pstmt = getPstmtWithArguments(strQuery, parPrepar, conn);
//      rst = pstmt.executeQuery();
//      CachedRowSet crs = new CachedRowSetImpl();
//      //Se llena el cachedrowset con los registros del resultset
//      crs.populate(rst);
//      //Cierro el cursor, este automaticamente cierra el resultset.
//      pstmt.close();
//      rst.close();
//      //rst.CLOSE_CURSORS_AT_COMMIT
//      return crs;
//    }

    
  public static void main(String[] args)
  {
    
    //ConnectionFactory cf = new ConnectionFactory("beneficios","beneficios");
	ConnectionFactory cf = new ConnectionFactory();
    
    try
    {
      Connection conn = cf.getConnection();
      cf.closeConnection(conn);
      
    }catch(SQLException e){
		System.err.println("/******** TDSUB - cwsub");
		e.printStackTrace();
		System.err.println("TDSUB - cwsub ********/");
    }
    
    //System.out.println(o[1].toString());
  } 


  public DataSource getDs()
  {
    return ds;
  }
}